<template>
  <el-upload
      ref="uploadRef"
      v-model:file-list="fileList"
      style="width: 100%"
      :auto-upload="false"
      :before-remove="beforeRemove"
      :class="{
      'custom-upload': config.limit == null || config.limit == 1,
      'custom-upload-mini': config.mini == 1
    }"
      :list-type="config.type == 'file' ? 'picture' : 'picture-card'"
      :limit="config.limit || 10"
      :accept="config.accept || '*'"
      :multiple="config.limit > 1"
      :on-exceed="handleExceed"
      :on-change="onChange"
  >
    <el-icon
        v-if="config.type != 'file'"
        style="font-size: 18px; color: #4e5969"
    ><Plus
    /></el-icon>
    <div v-if="config.type == 'file'" class="el-upload__text">
      <el-button type="primary">选择文件</el-button>
      <div v-if="config.accept">只支持 {{ config.accept }}</div>
    </div>

    <template #file="{ file }">
      <div style="width: 100%; height: 100%">
        <div
            v-if="config.type == 'file'"
            style="
            line-height: 1.8;
            display: flex;
            justify-content: space-between;
            align-items: center;
            width: 68%;
          "
        >
          <span>{{ FileUtils.getFileNameFromUrl(file.url) }}</span>
          <el-icon @click="handleRemove(file)"><CloseBold /></el-icon>
        </div>
        <video
            v-if="config.type == 'video'"
            object-fit="cover"
            :src="file.url"
        />
        <img
            v-else-if="config.type != 'file'"
            class="el-upload-list__item-thumbnail"
            :src="file.url"
            alt=""
        />
        <span v-if="config.type != 'file'" class="el-upload-list__item-actions">
          <span
              class="el-upload-list__item-preview"
              @click="handlePictureCardPreview(file, config.type)"
          >
            <el-icon v-if="config.type == 'video'"><video-play /></el-icon>
            <el-icon v-else><zoom-in /></el-icon>
          </span>
          <span class="el-upload-list__item-delete" @click="handleRemove(file)">
            <el-icon><Delete /></el-icon>
          </span>
        </span>
        <div>
          <el-progress
              v-if="file.status != 'success'"
              :text-inside="true"
              :stroke-width="8"
              :width="80"
              style="margin-bottom: 4px"
              :percentage="file.percentage"
          />
        </div>
      </div>
    </template>

    <template v-if="config.tip" #tip>
      <div class="el-upload__tip">{{ config.tip }}</div>
    </template>
  </el-upload>

  <el-dialog v-model="dialogVisible">
    <img style="width: 100%" :src="dialogImageUrl" alt="图片预览" />
  </el-dialog>

  <BaseDialog
      v-model="videoDialogVisible"
      title="视频预览"
      style="width: 800px"
  >
    <video
        controls
        style="width: 800px; height: 500px"
        :src="dialogImageUrl"
        alt="图片预览"
    />
  </BaseDialog>
</template>

<script lang="ts" setup>
import { ElMessage, ElMessageBox, UploadFile } from "element-plus";
import type { UploadProps, UploadUserFile } from "element-plus";
import UploadApi from "/@/api/uploadApi";
import {
  CloseBold,
  Delete,
  Plus,
  VideoPlay,
  ZoomIn
} from "@element-plus/icons-vue";
import Sortable from "sortablejs";
import BaseDialog from "/@/templates/BaseDialog.vue";
import { FileUtils } from "/@/utils/FileUtils.ts";

const props = defineProps({
  modelValue: {},
  config: {
    default: {
      multiple: false,
      limit: 10,
      showCard: true
    }
  }
});
const emits = defineEmits(["update:modelValue","update:fileName"]);

const uploadRef = ref(null);
const videoDialogVisible = ref(false);
const dialogImageUrl = ref("");
const dialogVisible = ref(false);

const fileList = ref<UploadUserFile[]>([]);
const uploadedFiles = ref<UploadUserFile[]>([]); // modelValue -> 已上传文件

// 合并上传中 + 已上传文件
const mergeFileList = () => {
  const uploading = fileList.value.filter(f => !f.uploaded);
  fileList.value = [...uploadedFiles.value, ...uploading];
};

// 初始化回显的文件（已上传）
const initData = () => {
  const urls = typeof props.modelValue === "string" && props.modelValue
      ? props.modelValue.split(",").filter(Boolean)
      : [];

  uploadedFiles.value = urls.map((url, i) => ({
    name: url.split("/").pop() || `已上传-${i}`,
    url,
    status: "success",
    uid: `uploaded-${i}`,
    uploaded: true
  }));

  mergeFileList();
};

// 初始化或 modelValue 变化时
watch(
    () => props.modelValue,
    () => {
      initData();
    },
    { immediate: true }
);

// 预览
const handlePictureCardPreview = (file: UploadFile, type) => {
  dialogImageUrl.value = file.url!;
  if (type == "video") {
    videoDialogVisible.value = true;
  } else {
    dialogVisible.value = true;
  }
};

// 文件超出限制
const handleExceed: UploadProps["onExceed"] = (files, uploadFiles) => {
  ElMessage.warning(`限制为${props.config.limit}个文件，当前共选择了${files.length + uploadFiles.length}个`);
};

// 删除文件
const handleRemove = (file: UploadFile) => {
  const index = fileList.value.findIndex(f => f.uid === file.uid);
  if (index !== -1) {
    fileList.value.splice(index, 1);
    updateModelValue();
  }
};

// 删除确认
const beforeRemove: UploadProps["beforeRemove"] = file => {
  return ElMessageBox.confirm(`是否删除文件 ${file.name}？`, {
    draggable: true
  }).then(() => true, () => false);
};

// 上传变化：来一个上传一个
const onChange = (uploadFile: UploadFile) => {
  const uid = uploadFile.uid;
  const formData = new FormData();
  formData.append("file", uploadFile.raw!);
  if (props.config.param){
    for (const [key,value] of Object.entries(props.config.param)){
      formData.append(key,value)
    }
  }

  UploadApi.upload(formData, progress => {
    const target = fileList.value.find(f => f.uid === uid);
    if (target) target.percentage = Math.floor(progress.progress * 100);
  }).then(res => {
    const { success,message,data } = res;
    const target = fileList.value.find(f => f.uid === uid);
    if (!target) return;

    if (!success) {
      $baseMessage(`上传失败：${message}`, 'success', 'vab-hey-message-success');
      const idx = fileList.value.findIndex(f => f.uid === uid);
      if (idx !== -1) fileList.value.splice(idx, 1);
      return;
    }

    Object.assign(target, {
      name: uploadFile.name,
      url: data,
      status: "success",
      uploaded: true
    });

    updateModelValue();
  });

  // 添加到 fileList（上传中）
  const already = fileList.value.find(f => f.uid === uid);
  if (!already) {
    fileList.value.push({
      name: uploadFile.name,
      status: "uploading",
      uid,
      percentage: 0,
      raw: uploadFile.raw
    });
  }
};

// 更新外部 v-model：只传已上传的 URL
const updateModelValue = () => {
  const urls = fileList.value
      .filter(file => file.status === "success" && file.url && !file.url.startsWith("blob:"))
      .map(file => file.url);
    console.log("upate upload url:",urls.join(","))
  const fileNameList = fileList.value.filter(file=>file.status === "success").map(x=>x.name.split(".")[0])
  emits("update:modelValue", urls.join(","));
  emits("update:fileName", fileNameList.join(","));
};
// 拖动排序
onMounted(() => {
  const el = uploadRef.value?.$el?.querySelector(".el-upload-list");
  if (el) {
    Sortable.create(el, {
      animation: 150,
      onEnd({ oldIndex, newIndex }) {
        if (oldIndex === newIndex) return;
        const moved = fileList.value.splice(oldIndex, 1)[0];
        fileList.value.splice(newIndex, 0, moved);
        updateModelValue(); // 拖动顺序也会影响最终 URL 顺序
      }
    });
  }
});
</script>

<style lang="scss" scoped>
.custom-upload {
  :deep() {
    .el-upload-list.el-upload-list--picture-card li:not(:empty) + div {
      display: none;
    }
  }
}

.custom-upload-mini {
  :deep() {
    .el-upload.el-upload--picture-card {
      width: 44px !important;
      height: 44px !important;
    }
    .el-upload-list--picture-card .el-upload-list__item {
      width: 44px !important;
      height: 44px !important;
    }
  }
}
.el-upload-list--picture-card .el-progress {
  width: 80px;
}
</style>
